package com.cindata

import grails.converters.JSON
import grails.gorm.transactions.Transactional
import net.sf.jasperreports.engine.JasperCompileManager
import net.sf.jasperreports.engine.JasperRunManager
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*
import org.grails.web.util.WebUtils

@Secured(['ROLE_ADMINISTRATOR'])
@Transactional()
class JasperFileController {

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def componentService

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond JasperFile.list(params), model:[jasperFileCount: JasperFile.count()]
    }

    def show(JasperFile jasperFile) {
        respond jasperFile
    }

    def create() {
        respond new JasperFile(params)
    }

    @Transactional
    def save(JasperFile jasperFile) {

        println jasperFile.errors

        if (jasperFile == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (jasperFile.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond jasperFile.errors, view:'create'
            return
        }

        jasperFile.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), jasperFile.id])
                redirect jasperFile
            }
            '*' { respond jasperFile, [status: CREATED] }
        }
    }

    def edit(JasperFile jasperFile) {
        respond jasperFile
    }

    @Transactional
    def update(JasperFile jasperFile) {

        if (jasperFile == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (jasperFile.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond jasperFile.errors, view:'edit'
            return
        }

        jasperFile.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), jasperFile.id])
                redirect jasperFile
            }
            '*'{ respond jasperFile, [status: OK] }
        }
    }

    @Transactional
    def delete(JasperFile jasperFile) {

        if (jasperFile == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        jasperFile.delete flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), jasperFile.id])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'jasperFile.label', default: 'JasperFile'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    @Transactional
    def uploadAvatar()
    {
        def jasperFile = new JasperFile()
        def file = request.getFile("file")
        if (file.empty)
        {
            flash.message = message(code: '请选择要上传的文件')
            respond jasperFile, view: 'create'
            return
        }
        def fileSize = request.getContentLength()
        if (fileSize > 1024*1024*5)
        {
            flash.message = message(code: '文件大小不能超过5M')
            respond jasperFile, view: 'create'
            return
        }
        def fileOrgName = file?.getOriginalFilename()
        def fileType = fileOrgName?.split('\\.')[-1]?.toLowerCase()
        def fileName = fileOrgName?.split('\\.')[0]
        if (fileType != 'jrxml')
        {
            flash.message = message(code: '文件格式不支持')
            respond jasperFile, view: 'create'
            return
        }
        def hostAddress = WebUtils.retrieveGrailsWebRequest().getBaseUrl()
        def newFileName = fileName + "_" + new java.text.SimpleDateFormat('MMddHHmmss').format(new Date())
        File fileImage = new File(servletContext.getRealPath("/"), "images/${newFileName}.${fileType}")
        file.transferTo(fileImage)

        def o = [:]
        def files = []
        def sfile = [:]
        sfile['thumbnailUrl'] = ''
        sfile['name'] = "${newFileName}.${fileType}"
        sfile['fileUrl'] = "${hostAddress}/static/images/${newFileName}.${fileType}"
        files.add(sfile)
        o['files'] = files
        render o as JSON
    }

    @Secured(['ROLE_ADMINISTRATOR'])
    def downloadJasperReport()
    {
        def jasperFile = JasperFile.findById(params.id)
        def map = componentService.evaluate(jasperFile?.component, jasperFile)
        if (!(map instanceof Map) || !map?.data) 
        {
            flash.message = "未找到数据或数据格式不对！"
            redirect action: 'index'
            return
        }
        println "map:" + map
        def beanColDataSource = new JRBeanCollectionDataSource(map?.data)
        def parameters = [:]
        def filebyte
        def fileName = jasperFile.fileUrl.substring(jasperFile.fileUrl.lastIndexOf("/")+1)
        def jasperfile = servletContext.getRealPath("/") + "images/" + fileName
        println "jasperfile:" + jasperfile
        if (params.format == "PDF")
        {
            filebyte = JasperRunManager.runReportToPdf(JasperCompileManager.compileReportToFile(jasperfile),parameters,beanColDataSource)
            OutputStream out
            try
            {
                out = response.getOutputStream()
                out.write(filebyte,0,filebyte.length)
                out.flush()
                out.close()
            }
            catch (Exception e)
            {
                e.printStackTrace()
            }
            return
        }
        else if (params.format == "HTML")
        {
            filebyte = JasperRunManager.runReportToHtmlFile(JasperCompileManager.compileReportToFile(jasperfile),parameters,beanColDataSource)
            OutputStream out
            try
            {
                out = response.getOutputStream()
                def inputStream = new FileInputStream(filebyte)
                byte[] buffer = new byte[1024]
                int i = -1
                while ((i = inputStream.read(buffer)) != -1) {
                    out.write(buffer, 0, i)
                }
                out.flush()
                out.close()
                inputStream.close()
            }
            catch (Exception e)
            {
                e.printStackTrace()
            }
            return
        }
    }
}
